home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
math
/
alged34.zip
/
ALGEDSRC.ZIP
/
ALGSHOW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-06
|
15KB
|
583 lines
/*--------------------------------------------------------------------
Alged: Algebra Editor henckel@vnet.ibm.com
Copyright (c) 1994 John Henckel
Permission to use, copy, modify, distribute and sell this software
and its documentation for any purpose is hereby granted without fee,
provided that the above copyright notice appear in all copies.
*/
#include "alged.h"
#include <alloc.h>
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The following functions relate to displaying expressions on the
screen.
*/
/*-----------------------------------------------------------------
twirl - this spins a little status indicator on the bottom
of the display to reassure the user in long calculations.
*/
void twirl(void) {
static char c[] = "/-\\|";
static int i=0;
gotoxy(5,ti.screenheight);
putch(c[i]);
if (++i > 3) i=0;
}
/*--------------------------------------------------------------------
debug dump
*/
void dumpnode(node *p,int tab) {
int i;
for (i=0; i<tab; ++i) putch(' ');
cprintf("%p %d %d (%d %d) %d '%s'\r\n",p,p->kind,p->nump,
p->px,p->py,p->sy,p->name);
for (i=0; i<p->nump; ++i)
dumpnode(p->parm[i],tab+2);
}
/*--------------------------------------------------------------------
re compute size of each node
*/
void resize(node *p,int ppr) {
double x;
int mpr,i;
mpr = pr[p->kind];
p->ay = 0;
switch (p->kind) {
case NUM:
x = fabs(p->value);
p->name[0] = 0;
if (p->value<0) strcat(p->name,"-");
if (x==M_PI) strcat(p->name,piname);
else if (x==M_E) strcat(p->name,ename);
else if (x==HUGE_VAL) strcat(p->name,infname);
else if (ch8 && x==0.5) strcat(p->name,halfname);
else if (ch8 && x==0.25) strcat(p->name,qtrname);
else sprintf(p->name,"%1.15G",p->value);
p->sy=1;
p->sx=strlen(p->name);
if (!point && strchr(p->name,'.')) *strchr(p->name,'.') = ',';
break;
case BAD:
strcpy(p->name,errname); /* fall thru */
case VAR:
p->sy=1;
p->sx=strlen(p->name);
break;
case EQU:
case ADD:
case SUB:
p->sx = 3;
if (mpr<ppr) p->sx += 2; /* parens */
resize(p->lf,mpr);
resize(p->rt,mpr+1); /* +1 = a hack */
p->sy = max(p->lf->sy,p->rt->sy);
p->sx += p->lf->sx + p->rt->sx;
strcpy(p->name,kname[p->kind]);
break;
case MUL:
p->sx = 1;
if (mpr<ppr) p->sx += 2; /* parens */
resize(p->lf,mpr);
resize(p->rt,mpr+1); /* +1 = a hack */
p->sy = max(p->lf->sy,p->rt->sy);
p->sx += p->lf->sx + p->rt->sx;
strcpy(p->name,kname[p->kind]);
break;
case DIV:
resize(p->lf,1); /* 1 = div suppresses parens */
resize(p->rt,1);
p->sx = max(p->lf->sx,p->rt->sx) + 2;
p->sy = p->lf->sy + p->rt->sy + 1;
p->ay = p->lf->sy - p->rt->sy;
if (p->ay <0) p->ay--;
p->ay /= 2;
if (mpr<ppr) p->sx += 2; /* parens */
strcpy(p->name,kname[p->kind]);
break;
case EXP:
resize(p->lf,mpr+1);
resize(p->rt,mpr);
p->sx = p->lf->sx + p->rt->sx;
p->sy = p->lf->sy + p->rt->sy;
p->ay = p->rt->sy - p->lf->sy;
if (p->ay >0) p->ay++;
p->ay /= 2;
if (mpr<ppr) p->sx += 2; /* parens */
strcpy(p->name,kname[p->kind]);
break;
case FUN:
p->sx = strlen(p->name) + 1; /* 2 parens JDH check this! */
p->sy = 0;
for (i=0; i<p->nump; ++i) {
resize(p->parm[i],mpr);
setmax(p->sy,p->parm[i]->sy);
p->sx += 1 + p->parm[i]->sx; /* 1 comma */
}
break;
default:
printf(msg[14]);
pause;
}
}
/*--------------------------------------------------------------------
leftpar - print a left parenthesis
*/
void leftpar(int h) {
int i;
if (h<2) {
putch('('); return; }
relxy(0,-h/2);
putch(ulc);
for (i=0; i<h-2; ++i) {
relxy(-1,1);
putch(vline);
}
relxy(-1,1);
putch(llc);
}
/*--------------------------------------------------------------------
rightpar - print a right parenthesis
*/
void rightpar(int h) {
int i;
if (h<2) {
putch(')'); return; }
relxy(0,-h/2);
putch(urc);
for (i=0; i<h-2; ++i) {
relxy(-1,1);
putch(vline);
}
relxy(-1,1);
putch(lrc);
}
/*-----------------------------------------------------------------
fix attributes
*/
int fixattr(node *p) {
gettextinfo(&ti);
if (p==src) textattr(bold1);
return ti.attribute;
}
#define seen (x > 0 && x < ti.screenwidth)
/*--------------------------------------------------------------------
print expression
*/
void show(node *p,int ppr,int x,int y) {
int mpr,i,z,s0,s1,attr;
mpr = pr[p->kind];
if (yadj) y = y + p->ay; /* adjust y */
gotoxy(x,y);
attr=fixattr(p); /* save old attribute */
switch (p->kind) {
case NUM:
case BAD:
case VAR:
p->px = x; p->py = y;
i = strlen(p->name); z = 0;
if (x > ti.screenwidth) break;
if (i+x > ti.screenwidth) i = ti.screenwidth - x;
if (x < 1) { gotoxy(1,y); z = -x; }
if (z < i) cprintf("%.*s",i-z,p->name+z);
break;
case EQU:
case ADD:
case SUB:
if (mpr<ppr) { if (seen) leftpar(p->sy); ++x; } /* parens */
show(p->lf,mpr,x,y);
x += p->lf->sx + 1;
gotoxy(x-1,y);
fixattr(p);
if (seen) cprintf(" %s ",kname[p->kind]);
show(p->rt,mpr+1,x+2,y);
p->px = x; p->py = y;
if (mpr<ppr) {
x += 2+p->rt->sx;
gotoxy(x,y);
fixattr(p);
if (seen) rightpar(p->sy); /* parens */
}
break;
case MUL:
if (mpr<ppr) { if (seen) leftpar(p->sy); ++x; } /* parens */
show(p->lf,mpr,x,y);
x += p->lf->sx;
gotoxy(x,y);
fixattr(p);
if (seen) cputs(ch8 ? kname[p->kind] : "*");
show(p->rt,mpr+1,x+1,y);
p->px = x; p->py = y;
if (mpr<ppr) {
x += 1+p->rt->sx;
gotoxy(x,y);
fixattr(p);
if (seen) rightpar(p->sy); /* parens */
}
break;
case DIV:
if (seen) for (i=0; i<p->sx; ++i) {
if (x+i < ti.screenwidth) putch(hline);
}
else if (x<1 && 0<(i=x+p->sx)) {
gotoxy(1,y); while (--i) putch(hline);
}
p->px = x; p->py = y;
if (mpr<ppr) {
gotoxy(x,y);
if (seen) leftpar(p->sy); /* parens */
}
show(p->lf,1,x + (p->sx - p->lf->sx)/2,
y - (p->lf->sy + 1)/2);
fixattr(p);
show(p->rt,1,x + (p->sx - p->rt->sx)/2,
y + (p->rt->sy + 2)/2);
if (mpr<ppr) {
x+=p->sx-1;
gotoxy(x,y);
fixattr(p);
if (seen) rightpar(p->sy); /* parens */
}
break;
case EXP:
if (mpr<ppr) { if (seen) leftpar(p->sy); ++x; } /* parens */
show(p->rt,mpr ,x + p->lf->sx,y - (p->rt->sy + 1)/2);
fixattr(p);
show(p->lf,mpr+1,x, y + (p->lf->sy + 0)/2);
p->px = x + p->lf->sx - 1;
p->py = y - 1;
if (mpr<ppr) {
x += p->sx-2;
gotoxy(x,y);
fixattr(p);
if (seen) rightpar(p->sy); /* parens */
}
break;
case FUN:
p->px = x; p->py = y;
if (seen) {
cputs(p->name);
leftpar(p->sy);
}
x += strlen(p->name) + 1;
for (i=0; ; ) {
show(p->parm[i],mpr,x,y);
x += p->parm[i]->sx;
gotoxy(x,y);
fixattr(p);
if (++i >= p->nump) break;
if (seen) putch(comma);
++x;
}
if (seen) rightpar(p->sy); /* parens */
break;
default:
printf(msg[15]);
pause;
}
textattr(attr);
}
/*-----------------------------------------------------------------
This test the integrity of the heap and returns the amount of
space USED.
*/
long heapused() {
struct heapinfo hi; long t=0;
if (heapcheck()<0) {
printf(msg[28]); pause;
return -1;
}
hi.ptr=NULL;
while (heapwalk(&hi)==2)
if (hi.in_use) t+=hi.size;
return t;
}
/*------------------------------------------------------------